#include <QtGui>

#include "cuboidDialog.h"
#include "src/vector3d.h"
#include "src/color.h"

CuboidDialog::CuboidDialog(int _id, QWidget *_parent)
    : QDialog(_parent), id(_id){

    setWindowTitle(QString::fromUtf8("Novo cubóide"));

    cuboid = NULL;
    colorR = colorG = colorB = colorAlpha = 255;
    minX = minY = minZ = 0.0;
    maxX = maxY = maxZ = 1.0;
    rotationX = 0;
    rotationY = 0;
    rotationZ = 0;
    onlyRotated = true;
    rotated = false;
    onlyChangedColor = true;

    createLayout();
}

CuboidDialog::CuboidDialog(CuboidPrimitive *_cuboid, ObjectTreeItem *_item, QWidget *_parent)
    : QDialog(_parent), cuboid(_cuboid), item(_item){

    setWindowTitle(QString::fromUtf8("Modificar objeto ").append(QString::number(_cuboid->getId())));

    const Color &color = cuboid->getColor();
    colorR = color.red * 255;
    colorG = color.green * 255;
    colorB = color.blue * 255;
    colorAlpha = color.alpha * 255;

    Vector3D min = cuboid->getPoint(0);
    minX = min.x;
    minY = min.y;
    minZ = min.z;

    Vector3D max = cuboid->getPoint(7);
    maxX = max.x;
    maxY = max.y;
    maxZ = max.z;
    rotationX = 0;
    rotationY = 0;
    rotationZ = 0;
    onlyRotated = true;
    rotated = false;
    onlyChangedColor = true;

    createLayout();
}

CuboidDialog::~CuboidDialog(){
    delete colorPushButton;
    delete minXDoubleSpinBox;
    delete minYDoubleSpinBox;
    delete minZDoubleSpinBox;
    delete maxXDoubleSpinBox;
    delete maxYDoubleSpinBox;
    delete maxZDoubleSpinBox;
}

void CuboidDialog::createLayout(){
    QLabel *minXLabel = new QLabel(tr("X:"));

    minXDoubleSpinBox = new QDoubleSpinBox();
    minXDoubleSpinBox->setRange(-50.0, 50.0);
    minXDoubleSpinBox->setSingleStep(1.0);
    minXDoubleSpinBox->setValue(minX);
    connect(minXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeMinX(double)));


    QLabel *minYLabel = new QLabel(tr("Y:"));

    minYDoubleSpinBox = new QDoubleSpinBox();
    minYDoubleSpinBox->setRange(-50.0, 50.0);
    minYDoubleSpinBox->setSingleStep(1.0);
    minYDoubleSpinBox->setValue(minY);
    connect(minYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeMinY(double)));


    QLabel *minZLabel = new QLabel(tr("Z:"));

    minZDoubleSpinBox = new QDoubleSpinBox();
    minZDoubleSpinBox->setRange(-50.0, 50.0);
    minZDoubleSpinBox->setSingleStep(1.0);
    minZDoubleSpinBox->setValue(minZ);
    connect(minZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeMinZ(double)));


    QHBoxLayout *minLayout = new QHBoxLayout;
    minLayout->addWidget(minXLabel);
    minLayout->addWidget(minXDoubleSpinBox);
    minLayout->addStretch(1);
    minLayout->addWidget(minYLabel);
    minLayout->addWidget(minYDoubleSpinBox);
    minLayout->addStretch(1);
    minLayout->addWidget(minZLabel);
    minLayout->addWidget(minZDoubleSpinBox);
    minLayout->addStretch(1);

    QGroupBox *minGroupBox = new QGroupBox(QString::fromUtf8("Ponto mínimo"));
    minGroupBox->setLayout(minLayout);


    QLabel *maxXLabel = new QLabel(tr("X:"));

    maxXDoubleSpinBox = new QDoubleSpinBox();
    maxXDoubleSpinBox->setRange(-50.0, 50.0);
    maxXDoubleSpinBox->setSingleStep(1.0);
    maxXDoubleSpinBox->setValue(maxX);
    connect(maxXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeMaxX(double)));


    QLabel *maxYLabel = new QLabel(tr("Y:"));

    maxYDoubleSpinBox = new QDoubleSpinBox();
    maxYDoubleSpinBox->setRange(-50.0, 50.0);
    maxYDoubleSpinBox->setSingleStep(1.0);
    maxYDoubleSpinBox->setValue(maxY);
    connect(maxYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeMaxY(double)));


    QLabel *maxZLabel = new QLabel(tr("Z:"));

    maxZDoubleSpinBox = new QDoubleSpinBox();
    maxZDoubleSpinBox->setRange(-50.0, 50.0);
    maxZDoubleSpinBox->setSingleStep(1.0);
    maxZDoubleSpinBox->setValue(maxZ);
    connect(maxZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeMaxZ(double)));


    QHBoxLayout *maxLayout = new QHBoxLayout;
    maxLayout->addWidget(maxXLabel);
    maxLayout->addWidget(maxXDoubleSpinBox);
    maxLayout->addStretch(1);
    maxLayout->addWidget(maxYLabel);
    maxLayout->addWidget(maxYDoubleSpinBox);
    maxLayout->addStretch(1);
    maxLayout->addWidget(maxZLabel);
    maxLayout->addWidget(maxZDoubleSpinBox);
    maxLayout->addStretch(1);

    QGroupBox *maxGroupBox = new QGroupBox(QString::fromUtf8("Ponto máximo"));
    maxGroupBox->setLayout(maxLayout);



    QLabel *rotateXLabel = new QLabel(QString::fromUtf8("X:"));

    QComboBox *rotateXComboBox = new QComboBox();
    rotateXComboBox->addItem(QString::fromUtf8("0°"));
    rotateXComboBox->addItem(QString::fromUtf8("90°"));
    rotateXComboBox->addItem(QString::fromUtf8("180°"));
    rotateXComboBox->addItem(QString::fromUtf8("270°"));
    rotateXComboBox->setCurrentIndex(rotationX);
    connect(rotateXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeRotationX(int)));

    QLabel *rotateYLabel = new QLabel(QString::fromUtf8("Y:"));

    QComboBox *rotateYComboBox = new QComboBox();
    rotateYComboBox->addItem(QString::fromUtf8("0°"));
    rotateYComboBox->addItem(QString::fromUtf8("90°"));
    rotateYComboBox->addItem(QString::fromUtf8("180°"));
    rotateYComboBox->addItem(QString::fromUtf8("270°"));
    rotateYComboBox->setCurrentIndex(rotationY);
    connect(rotateYComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeRotationY(int)));

    QLabel *rotateZLabel = new QLabel(QString::fromUtf8("Z:"));

    QComboBox *rotateZComboBox = new QComboBox();
    rotateZComboBox->addItem(QString::fromUtf8("0°"));
    rotateZComboBox->addItem(QString::fromUtf8("90°"));
    rotateZComboBox->addItem(QString::fromUtf8("180°"));
    rotateZComboBox->addItem(QString::fromUtf8("270°"));
    rotateZComboBox->setCurrentIndex(rotationZ);
    connect(rotateZComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeRotationZ(int)));

    QHBoxLayout *rotationLayout = new QHBoxLayout;
    rotationLayout->addWidget(rotateXLabel);
    rotationLayout->addWidget(rotateXComboBox);
    rotationLayout->addStretch(1);
    rotationLayout->addWidget(rotateYLabel);
    rotationLayout->addWidget(rotateYComboBox);
    rotationLayout->addStretch(1);
    rotationLayout->addWidget(rotateZLabel);
    rotationLayout->addWidget(rotateZComboBox);
    rotationLayout->addStretch(1);

    QGroupBox *rotationGroupBox = new QGroupBox(QString::fromUtf8("Rotação"));
    rotationGroupBox->setLayout(rotationLayout);

    colorPushButton = new QPushButton(tr("Cor"));
//    colorPushButton->setFlat(true);
    connect(colorPushButton, SIGNAL(clicked()), this, SLOT(changeColor()));
    setButtonColor();


    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(acceptAndCreate()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    buttonBox->setLocale(QLocale(QLocale::Portuguese, QLocale::Brazil));

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(minGroupBox);
    mainLayout->addWidget(maxGroupBox);
    mainLayout->addWidget(rotationGroupBox);
    mainLayout->addWidget(colorPushButton);
    mainLayout->addWidget(buttonBox);
    mainLayout->addStretch(1);

    setLayout(mainLayout);
}

void CuboidDialog::setButtonColor(){
    //    QString colorStr = QString::fromUtf8("color: rgb(255, 255, 255);\n" "background-color: rgb(85, 0, 0, 255);");
    QString colorStr;
    if(colorR + colorB + colorG + colorAlpha < 600){
        colorStr = QString::fromUtf8("color: rgb(255, 255, 255);\n");
    }else{
        colorStr = QString::fromUtf8("color: rgb(0, 0, 0);\n");
    }
    colorStr.append(QString::fromUtf8("background-color: rgb("));
    colorStr.append(QString::number(colorR));
    colorStr.append(QString::fromUtf8(", "));
    colorStr.append(QString::number(colorG));
    colorStr.append(QString::fromUtf8(", "));
    colorStr.append(QString::number(colorB));
    colorStr.append(QString::fromUtf8(", "));
    colorStr.append(QString::number(colorAlpha));
    colorStr.append(QString::fromUtf8(");"));

    colorPushButton->setStyleSheet(colorStr);
}

void CuboidDialog::acceptAndCreate(){
    if(!cuboid){
        cuboid = new CuboidPrimitive(Vector3D(minX, minY, minZ), Vector3D(maxX, maxY, maxZ), Color(colorR / 255.0, colorG / 255.0, colorB / 255.0, colorAlpha / 255.0), id);
        cuboid->rotate(rotationX, rotationY, rotationZ);
        done(cuboid);

        emit redoOctree(cuboid);
    }else{
        cuboid->setColor(Color(colorR / 255.0, colorG / 255.0, colorB / 255.0, colorAlpha / 255.0));
        cuboid->setAllPoints(Vector3D(minX, minY, minZ), Vector3D(maxX, maxY, maxZ));
        cuboid->rotate(rotationX, rotationY, rotationZ);


        if(rotated && onlyRotated){
            emit rotateOctree(cuboid, rotationX, rotationY, rotationZ);
            accept();
            return;
        }

        if(onlyChangedColor){
            accept();
            return;
        }

        QTreeWidgetItem *parent = item->parent();
        if(parent == NULL)
            emit redoOctree(cuboid);
        else{
            while(parent->parent() != NULL){
                parent = parent->parent();
            }
            emit redoOctree(((ObjectTreeItem *)parent)->getObject());
        }
    }



    accept();
}

void CuboidDialog::changeColor(){
    QColor color = QColorDialog::getColor(QColor(colorR, colorG, colorB, colorAlpha), this, "Escolha a cor", QColorDialog::ShowAlphaChannel);
    if (color.isValid()){
        colorR = color.red();
        colorG = color.green();
        colorB = color.blue();
        colorAlpha = color.alpha();
    }
    setButtonColor();
}

void CuboidDialog::changeMinX(double _x){
    onlyRotated = false;
    onlyChangedColor = false;
    minX = _x;
    if(minX >= maxX){
        maxX = minX + 1;
        maxXDoubleSpinBox->setValue(maxX);
    }
}

void CuboidDialog::changeMinY(double _y){
    onlyRotated = false;
    onlyChangedColor = false;
    minY = _y;
    if(minY >= maxY){
        maxY = minY + 1;
        maxYDoubleSpinBox->setValue(maxY);
    }
}

void CuboidDialog::changeMinZ(double _z){
    onlyRotated = false;
    onlyChangedColor = false;
    minZ = _z;
    if(minZ >= maxZ){
        maxZ = minZ + 1;
        maxZDoubleSpinBox->setValue(maxZ);
    }
}

void CuboidDialog::changeMaxX(double _x){
    onlyRotated = false;
    onlyChangedColor = false;
    maxX = _x;
    if(maxX <= minX){
        minX = maxX - 1;
        minXDoubleSpinBox->setValue(minX);
    }
}

void CuboidDialog::changeMaxY(double _y){
    onlyRotated = false;
    onlyChangedColor = false;
    maxY = _y;
    if(maxY <= minY){
        minY = maxY - 1;
        minYDoubleSpinBox->setValue(minY);
    }
}

void CuboidDialog::changeMaxZ(double _z){
    onlyRotated = false;
    onlyChangedColor = false;
    maxZ = _z;
    if(maxZ <= minZ){
        minZ = maxZ - 1;
        minZDoubleSpinBox->setValue(minZ);
    }
}

void CuboidDialog::changeRotationX(int _x){
    rotated = true;
    onlyChangedColor = false;
    rotationX = _x;
}

void CuboidDialog::changeRotationY(int _y){
    rotated = true;
    onlyChangedColor = false;
    rotationY = _y;
}

void CuboidDialog::changeRotationZ(int _z){
    rotated = true;
    onlyChangedColor = false;
    rotationZ = _z;
}
